# ~*~ coding: utf-8 ~*~
from flask import request, views, render_template, jsonify, current_app
from apps.common.utils import timestamp_obj_to_str
from apps.common import response
from apps.extensions import db
from ..models import Permission, RolePermission
from ..menu import build_menu
from ..forms import PermissionCreateUpdateForm
from ..mixin import PermissionRequiredMixin, LoginRequiredMixin

__all__ = [
    'PermissionMenuAPI',  'PermissionListAPI', 'PermissionListView',
    'PermissionUpdateView', 'PermissionCreateView', 'PermissionDeleteView'
]


class PermissionMenuAPI(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'perms-permission-menu'

    def get(self):
        all_permissions = db.session.query(Permission).\
            order_by(Permission.sort.asc()). \
            order_by(Permission.create_time.asc()).\
            all()
        menus = build_menu(all_permissions)
        return jsonify(menus)


class PermissionListAPI(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'perms-permission-list'

    def get(self):
        permissions, count = Permission.get_queryset(order_by_list=(('create_time', 'asc'),), offset=0, limit=None)
        results = list()
        for permission in permissions:
            results.append({
                'id': permission.id,
                'pid': permission.pid,
                'name': permission.name,
                'module': permission.module,
                'controller': permission.controller,
                'action': permission.action,
                'icon': permission.icon,
                'is_menu': permission.is_menu,
                'sort': permission.sort,
                'create_time': timestamp_obj_to_str(permission.create_time),
            })

        resp = {
            "data": {
                "rows": results,
                "total": count
            }
        }
        return jsonify(resp)


class PermissionListView(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'perms-permission-list'

    def get(self):
        return render_template('perms/permission_list.html')


class PermissionUpdateView(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'perms-permission-update'

    def get(self, pk):
        from sqlalchemy.orm import aliased
        parent = aliased(Permission, name='parent')
        instance = db.session.query(Permission.id, Permission.name, Permission.pid, Permission.module,
                                    Permission.controller, Permission.action, Permission.is_menu,
                                    Permission.icon, Permission.sort, parent.name.label('pname')). \
            outerjoin(parent, Permission.pid == parent.id).\
            filter(Permission.id == str(pk)).\
            first()

        content = {
            'id': instance.id,
            'name': instance.name,
            'pid': instance.pid,
            'pname': instance.pname or '',
            'module': instance.module,
            'controller': instance.controller,
            'action': instance.action or '',
            'is_menu': instance.is_menu,
            'icon': instance.icon,
            'sort': instance.sort or '',
        }
        return render_template('perms/permission_update.html', **content)

    def post(self, pk):
        instance = db.session.query(Permission).get(str(pk))
        form = PermissionCreateUpdateForm(request.values)

        if form.validate_on_submit():
            _clean_data = form.data
            if _clean_data.get('name') != instance.name:
                if db.session.query(Permission).filter_by(name=_clean_data.get('name')).count():
                    return response.params_error({
                        'field': 'name',
                        'message': '权限名称不能重复'
                    })

            instance.update(**_clean_data)
            return response.success()
        else:
            return response.params_error(data=form.get_error())


class PermissionCreateView(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'perms-permission-create'

    def get(self):
        return render_template('perms/permission_create.html')

    def post(self):
        form = PermissionCreateUpdateForm(request.values)
        if form.validate():
            _clean_data = form.data
            if db.session.query(Permission).filter_by(name=_clean_data.get('name')).count():
                return response.params_error(data={
                    'field': 'name',
                    'message': '权限名称不能重复'
                })
            Permission.create(**_clean_data)
            return response.success()
        else:
            return response.params_error(data=form.get_error())


class PermissionDeleteView(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'perms-permission-create'

    def post(self, pk):
        instance = db.session.query(Permission).get(str(pk))
        try:
            instance.delete(commit=False)
            if db.session.query(Permission).filter(Permission.pid == instance.id).count():
                return response.params_error(data={
                    'message': '该权限有关联的下级权限不能直接删除'
                })
            db.session.query(RolePermission).filter(RolePermission.permission_id == instance.id).delete()
            db.session.commit()
            return response.success()
        except Exception as e:
            current_app.logger.error(e)
            db.session.rollback()
            return response.server_error(data={
                'message': "出现未知错误，请联系管理员！"
            })